package com.weifly.weistock.record.option;

import com.weifly.weistock.core.common.StockException;
import com.weifly.weistock.record.bo.MergeRecordResult;
import com.weifly.weistock.record.bo.RecordPair;
import com.weifly.weistock.record.option.domain.OptionRecordDto;
import com.weifly.weistock.record.option.domain.OptionYearDto;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 期权工具方法
 *
 * @author weifly
 * @since 2019/11/18
 */
public class OptionUtils {

    public static void checkEmpty(Object value, String message){
        if(value==null){
            throw new StockException(message);
        }
        if(value instanceof String){
            if(StringUtils.isBlank((String)value)){
                throw new StockException(message);
            }
        }else if(value instanceof List){
            if(((List)value).isEmpty()){
                throw new StockException(message);
            }
        }
    }

    public static void copyRecordProp(OptionRecordDto source, OptionRecordDto target) {
        // 共23个属性
        target.setDate(source.getDate());
        target.setContractName(source.getContractName());
        target.setContractCode(source.getContractCode());
        target.setStockName(source.getStockName());
        target.setStockCode(source.getStockCode());
        target.setBusinessName(source.getBusinessName());
        target.setOperationType(source.getOperationType());
        target.setHoldPosition(source.getHoldPosition());
        target.setTradePrice(source.getTradePrice());
        target.setTradeNumber(source.getTradeNumber());
        target.setTradeAmount(source.getTradeAmount());
        target.setFeeService(source.getFeeService());
        target.setFeeStamp(source.getFeeStamp());
        target.setFeeTransfer(source.getFeeTransfer());
        target.setFeeExtra(source.getFeeExtra());
        target.setFeeClear(source.getFeeClear());
        target.setClearAmount(source.getClearAmount());
        target.setAfterAmount(source.getAfterAmount());
        target.setAfterNumber(source.getAfterNumber());
        target.setEntrustCode(source.getEntrustCode());
        target.setTime(source.getTime());
        target.setPairList(source.getPairList());
        target.setDiffAmount(source.getDiffAmount());
    }

    public static void addRecordToYear(OptionYearDto yearDto, OptionRecordDto recordDto, MergeRecordResult result){
        // key规则：发生日期_成交时间_委托编号_买卖标志_合约编码
        String key = recordDto.getDate() + "_" + recordDto.getTime() + "_" + recordDto.getEntrustCode() + "_" + recordDto.getOperationType().getCode() + "_" + recordDto.getContractCode();
        OptionRecordDto targetDto = yearDto.getRecordMap().get(key);
        if(targetDto==null){
            yearDto.getRecordList().add(recordDto);
            yearDto.getRecordMap().put(key, recordDto);
            if(result!=null){
                result.setInsert(result.getInsert()+1);
            }
        }else{
            OptionUtils.copyRecordProp(recordDto, targetDto);
            if(result!=null){
                result.setUpdate(result.getUpdate()+1);
            }
        }
    }

    public static void addRecordToMap(Map<String, List<OptionRecordDto>> contractMap, OptionRecordDto recordDto) {
        List<OptionRecordDto> recordList = contractMap.get(recordDto.getContractCode());
        if(recordList==null){
            recordList = new ArrayList<>();
            contractMap.put(recordDto.getContractCode(), recordList);
        }
        recordList.add(recordDto);
    }

    public static void clearRecordPair(List<OptionRecordDto> recordList){
        for(OptionRecordDto record : recordList){
            if(record.getPairList()!=null){
                record.getPairList().clear();
            }
            record.setDiffAmount(null);
        }
    }

    public static String makePairAttr(OptionRecordDto recordDto){
        List<RecordPair> pairList = recordDto.getPairList();
        if(pairList==null || pairList.isEmpty()){
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<pairList.size();i++){
            RecordPair pair = pairList.get(i);
            // 输出index
            if(pair.getNumber()==recordDto.getTradeNumber()){
                sb.append(pair.getIndex());
            }else{
                sb.append(pair.getIndex());
                if(pair.getNumber()>1){
                    sb.append("(").append(pair.getNumber()).append(")");
                }
            }
            // 输出分隔符
            if(i<pairList.size()-1){
                sb.append(",");
            }
        }
        return sb.toString();
    }

    /**
     * 获得未配对成交量
     */
    public static int getNotPairNumber(OptionRecordDto record){
        int totalPairNumber = 0;
        if(record.getPairList()!=null){
            for(RecordPair pair : record.getPairList()){
                totalPairNumber += pair.getNumber();
            }
        }
        return record.getTradeNumber() - totalPairNumber;
    }

    /**
     * 是平仓操作，则返回true
     */
    public static boolean isCloseRecord(OptionRecordDto record){
        OptionConst.OperationType ot = record.getOperationType();
        // 备兑平仓 买入平仓 卖出平仓
        if(OptionConst.OperationType.TYPE_2.equals(ot)
                || OptionConst.OperationType.TYPE_4.equals(ot)
                || OptionConst.OperationType.TYPE_6.equals(ot)){
            return true;
        }

        // 买入 and 行权资金拨出
        if(OptionConst.OperationType.TYPE_7.equals(ot)){
            if(OptionConst.BusinessName.NAME_10.equals(record.getBusinessName())){
                return true;
            }
        }

        return false;
    }
}
